﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace Grishko.DataTier.SqlLibrary
{
    /// <summary>
    /// Список отражающий v_PropertyOf
    /// позволяет получить срез v_PropertyOf 
    /// по колеекции пар - свойство/значение
    /// используется как фильтр в  предложениях SqlLoadStatment
    /// </summary>
    
    public class vPropertyOfList : EntityList
    {
        public enum Options { Param, ParamValue, Value }
        public EntityList ParamList = new EntityList();
        public class ParamListItem : EntitySingle
        {
            public string Param { get; set; }
            public string Value { get; set; }
        }
        public override void Load()
        {
            string sql = GetSqlForTable(string.Empty);
            SecuretyContext SC = AppContext.GetSC();
            try
            {

                System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
                cmd.CommandText = sql;
                cmd.CommandType = System.Data.CommandType.Text;
                cmd.Connection = SC.Connection;
                SC.Connection.Open();

                SqlDataAdapter adp = new SqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                adp.Fill(ds);

                if (0 == ds.Tables.Count) return;

                DataTable tbl = ds.Tables[0];

                foreach (DataRow rw in tbl.Rows)
                {
                    this.Add(new EntitySingle() { ID = rw[0].ToString() });
                }

            }
            catch
            {
                return;
            }
            finally
            {
                SC.Connection.Close();
            }
        }

        /// <summary>
        /// Формирует Sql запрос для vPropertyOf =SourceViewName, выдает набор соответсвующий парам параметр / значение указанным в  ParamList
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="SourceViewName"></param>
        /// <returns></returns>
        public virtual string GetSqlForTable(string TableName)
        {

            string sql = string.Empty;
            if (0 != ParamList.Count)
            {
                string OnJoin = "#t.param+#t.value=" + ViewName + ".Param+" + ViewName + ".Value";
                switch (_SqlSearchOption)
                {
                    case Options.ParamValue:
                        OnJoin = "#t.param+#t.value=" + ViewName + ".Param+" + ViewName + ".Value";
                        break;
                    case Options.Param:
                        OnJoin = "#t.param=" + ViewName + ".Param";
                        break;
                    case Options.Value:
                        OnJoin = "#t.value=" + ViewName + ".Value";
                        break;
                }
                sql = "declare @xml as xml set @xml=' " + ParamList.ToXml(true) + "'";
                sql = sql + " SELECT  T.c.value('(@Param)[1]','varchar(max)') as param,	T.c.value('(@Value)[1]','varchar(max)') as Value INTO #t FROM    @xml.nodes('/EntityList/ParamListItem') T(c)";
                sql = sql + "declare @WhereCount as int select @WhereCount=count(*) from #t  insert into "+ TableName+" select id from (select id as ID,1 as ItemCount  from  " + ViewName + " join  #t on " + OnJoin + ")as res   group by res.ID,ItemCount having sum(ItemCount)= @WhereCount ";
            }
            else
            {
                sql = "Select id from  " + ViewName;
            }
            return sql;

        }

        private Options _SqlSearchOption = Options.ParamValue;
        /// <summary>
        /// В зависимости от выставленной опции - формируется поисковый запрос по ParamList
        /// По паре - параметр/значение, по параметру, по значению. По умолчанию параметр/значение
        /// </summary>        
        public Options SqlSearchOption { get { return _SqlSearchOption; } set { _SqlSearchOption = value; } }

        public string ViewName { get; set; }

    }
}
